package org.biblicalcontent.ui.navigator.views;

import java.util.ArrayList;
import java.util.List;

import org.biblicalcontent.ui.generiek.NavigatorContentProvider;
import org.eclipse.jface.viewers.IStructuredContentProvider;
import org.eclipse.jface.viewers.ITreeContentProvider;
import org.eclipse.jface.viewers.Viewer;
import org.eclipse.ui.IViewSite;

class ViewContentProvider implements IStructuredContentProvider, ITreeContentProvider {
	private TreeParent invisibleRoot;
	private final List<NavigatorContentProvider> contentProviders;
	private final IViewSite viewsite;

	public ViewContentProvider(IViewSite viewsite, List<NavigatorContentProvider> contentProviders) {
		this.viewsite = viewsite;
		this.contentProviders = contentProviders;
	}

	public void inputChanged(Viewer v, Object oldInput, Object newInput) {
	}

	public void dispose() {
	}

	public Object[] getElements(Object parent) {
		if (parent.equals(viewsite)) {
			if (invisibleRoot == null) {
				initialize();
			}
			return getChildren(invisibleRoot);
		}
		return getChildren(parent);
	}

	public Object getParent(Object child) {
		return null;
	}

	public Object[] getChildren(Object parent) {
		if (parent instanceof TreeParent) {
			return ((TreeParent) parent).getChildren();
		} else if (parent instanceof NavigatorContentProvider) {
			return new Object[] { ((NavigatorContentProvider) parent).getRootObject() };
		}

		for (NavigatorContentProvider provider : contentProviders) {
			if (provider.hasChildren(parent)) {
				return provider.getChildrenForParent(parent).toArray();
			}
		}
		return new Object[0];
	}

	public boolean hasChildren(Object parent) {
		if (parent instanceof TreeParent) {
			return ((TreeParent) parent).hasChildren();
		}
		if (parent instanceof NavigatorContentProvider) {
			return ((NavigatorContentProvider) parent).hasChildren(parent);
		}
		for (NavigatorContentProvider provider : contentProviders) {
			if (provider.hasChildren(parent)) {
				return true;
			}
		}
		return false;
	}

	/*
	 * We will set up a dummy model to initialize tree heararchy. In a real
	 * code, you will connect to a real model and expose its hierarchy.
	 */
	private void initialize() {
		invisibleRoot = new TreeParent("");
		for (NavigatorContentProvider provider : this.contentProviders) {
			invisibleRoot.addChild(provider);
		}
	}

	private class TreeParent {
		private ArrayList<NavigatorContentProvider> children = new ArrayList<NavigatorContentProvider>();

		public TreeParent(String name) {
			//
		}

		public void addChild(NavigatorContentProvider child) {
			children.add(child);
		}

		public void removeChild(NavigatorContentProvider child) {
			children.remove(child);
		}

		public NavigatorContentProvider[] getChildren() {
			return (NavigatorContentProvider[]) children.toArray(new NavigatorContentProvider[children.size()]);
		}

		public boolean hasChildren() {
			return children.size() > 0;
		}
	}
}